package com.wodan.zhongjinjicang.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.wodan.zhongjinjicang.common.constants.ClientApiConstants;
import com.wodan.zhongjinjicang.common.exception.BusinessException;
import com.wodan.zhongjinjicang.enums.BusinessErrorEnum;
import com.wodan.zhongjinjicang.frame.JsonBusinessMethodService;
import com.wodan.zhongjinjicang.service.ServiceTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @ClassName: ServiceTemplate
 * @Description: 业务处理模板
 * @author chenw
 * @date 2015-2-2 下午2:57:12
 * @history
 */
@Service
public class ServiceTemplateImpl implements ServiceTemplate, ApplicationContextAware {

	private static Logger logger = LoggerFactory.getLogger(ServiceTemplateImpl.class);


	/**
	 * spring上下文
	 */
	private ApplicationContext applicationContext;


	/**
	 * 返回json格式结果
	 */
	@Override
	public String executeJson(String serviceName, HttpServletRequest request, HttpServletResponse response,
			String sessionId, String message, CallbackHandler handler) {
		return handle(serviceName, request, response, sessionId, handler, message).toJSONString();
	}

	/**
	 * 返回json对象
	 */
	@Override
	public JSONObject executeJsonObject(String serviceName, HttpServletRequest request, HttpServletResponse response,
										String sessionId, String message,CallbackHandler handler) {
		return handle(serviceName, request, response, sessionId, handler, message);
	}

	private JSONObject handle(String serviceName, HttpServletRequest request, HttpServletResponse response,
			String sessionId, CallbackHandler handler, String message) {
		// 构建请求对象
		JSONObject reqJsonObj = new JSONObject();
		reqJsonObj.put(ClientApiConstants.SERVICE_NAME, serviceName);

		// 回调获取业务参数
		JSONObject contentJsonObj = handler.buildBizParams(request, response, sessionId, message);
		if (contentJsonObj == null) {
			contentJsonObj = new JSONObject();
		}
		reqJsonObj.put(ClientApiConstants.Data, contentJsonObj);
		reqJsonObj.put(ClientApiConstants.SESSION_ID, sessionId);

		// 调用具体业务
		JSONObject respJsonObj = callBussiness(reqJsonObj, request);
		return respJsonObj;
	}

	/**
	 * @Description: 调用具体业务
	 * @param reqJsonObj
	 * @param request
	 * @return
	 */
	private JSONObject callBussiness(JSONObject reqJsonObj, HttpServletRequest request) {
		long startTime = System.currentTimeMillis();

		String serviceName = reqJsonObj.getString(ClientApiConstants.SERVICE_NAME);
		JsonBusinessMethodService currBusinessMethodService = applicationContext.getBean(serviceName,
				JsonBusinessMethodService.class);

		try {

			if (logger.isDebugEnabled()) {
				logger.debug("找到业务执行Bean(" + serviceName + "):" + currBusinessMethodService);
			}

			JSONObject respContent = currBusinessMethodService.execute(reqJsonObj);
			JSONObject respJsonObj = new JSONObject();
			respJsonObj.put(ClientApiConstants.CODE, BusinessErrorEnum.SUCCESS.getCode());
			respJsonObj.put(ClientApiConstants.MSG, BusinessErrorEnum.SUCCESS.getDesc());
			respJsonObj.put(ClientApiConstants.Data, respContent);

			if (logger.isDebugEnabled()) {
				logger.debug("业务执行后返回的数据内容:" + respContent.toJSONString());
			}
			return respJsonObj;
		} catch (BusinessException e) {
			if (e.isLogExceptionStackTrance()) {
				logger.warn("业务处理过程出现异常.", e);
			} else {
				logger.warn("业务处理过程出现异常, {}", e.getMessage());
			}
			logger.error("请求报文内容：{}", reqJsonObj);
			JSONObject respContent = new JSONObject();
			respContent.put(ClientApiConstants.CODE, e.getErrCode());
			respContent.put(ClientApiConstants.MSG, e.getErrMsg());
			respContent.put(ClientApiConstants.Data, new JSONObject());
			return respContent;
		} finally {
			//实现公共逻辑
		}
	}

	/**
	 * @Description: 获取spring上下文
	 * @param applicationContext
	 * @throws BeansException
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}
